perm filename F8JUL7[3,ALS]1 blob
sn#291052 filedate 1977-07-07 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00012 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 * General remarks
C00008 00003 * RAM and SCRATCHPAD assignments
C00014 00004 * START
C00019 00005 * RASC SCRC EMPTY CAQ MPYR
C00024 00006 * FKT GMEN RFJN LFJN STMV
C00029 00007 * NEXT FIND RFJ LFJ RBJ LBJ JUMT AFT MAKE RARA
C00035 00008 * RFN LFN RBN LBN NORT
C00038 00009 * SELECT SELE
C00045 00010 * NORM FORE
C00047 00011 * EVAL
C00050 00012 * SQIN SQOU MVIN
C00055 ENDMK
C⊗;
* General remarks
We envision three levels of play which are personified by calling them
Robot Tom, Robot Dick and Robot Harry. Robot Tom will be the weakest
player. Less reprobation will be implied to the user than if the lowest
level were characterized as for the Beginner, and at the other end, less
undeserved credit will be claimed for the program's degree of
proficiency. The single letters T, D and H could be used to designate
these players. Depending upon what is decided as to the amount of
audio and visual text that can be generated, these three levels might be
further identified by calling the lowest level "Helpful Robot Tom", the
next as "Silent Robot Dick" and the highest level as "Mighty Robot Harry",
and the board could be displayed in diffrent colors for the three different
levels.
Under normal circumstances, the details of how these levels are adjusted
would be kept from the player. He would simply be advised to start by
playing Robot Tom and then if he can beat Robot Tom to try playing Robot
Dick and then finally to try playing Robot Harry.
In fact. it might be well to have Robot Tom be the default setting and to
allow the player the option of starting play immediately either by typing
in a move or by typing the character that tells the machine to play black.
This would simplify the use of the program for the very young child who
could be told by his parent to always play black and to simply enter his
opening move. Alternately the first question to the user might be "Do you
want to play Black against Robot TOM?", and then a "Y" reply would cause
the board to appear, properly oriented with Black pieces at the bottom.
An "N" reply would then lead to a list of questions, with subsequent
questions so phrased that an affirmative answer will be more likely than
a negative one and will usually lead to a termination of the questioning.
I strongly oppose the asking of too many questions of the inexperienced
user. Even on a much larger computer and with supposedly expert users
this causes an otherwise very useful program to be shunned. For example,
rather than asking if the user wants to use the Joy Stick, the program should
assume that he does if one is plugged in and assumes that he does not if
he removes the sticks.
The levels of play would be set by changes to the depth of ply to which
the search would be allowed to go and perhaps by the way that stored moves
would be used.
For the truely expert checker player, there should be a way to set the
play to even higher levels. Actually, this will not be difficult to do
but unfortunately the playing time may be unduely long, and it probably
would be unwise to let the casual user get into trouble by making these
levels readily available. The good checker player might welcome this
provision.
The user could be advised of this possibility in the literature supplied
with the cartridge and could be told to write in for information as to how
this is done. This could be used to generate a list of interested users
for a mailing list. These people would be prime candidates for other
cartridges and perhaps for a new model of the Video Brain when one is
developed.
It would also be possible to allow the user to set up any initial board
conditions that he choses, (a checker puzzle for example) rather than
having to start each game from scratch. Even the casual user might like
this feature as it would allow him to stop playing in the middle of a game
and to continue the interrupted game as a later time. To make this easy
to do the program should be able to list the board condition in standard
checker notation (so the user can copy it) rather than forcing the user to
generate this list himself or forcing him to make a picture of the board.
* RAM and SCRATCHPAD assignments
Tree data will be kept in RAM in blocks of 16 bytes, one for each ply depth.
These data will occupy 256 bytes starting at a location that has a second
address byte of 0. At the start of a game the first two blocks will be
loaded with the conditions that relate to a game with the machine playing
BLACK. If the player elects to play BLACK then the board conditions after
his move are loaded into the second block. Thereafter the second block
will be used as the board to start the tree search and the machines reply
will be returned in the first block.
This arrangement, while not essential, will greatly simplify address
computations during the tree search.
Data within each block will be located as follows:
Bytes Contents
0 thru 3 ACTIVE pieces
4 thru 7 PASSIVE pieces
8 thru 11 KINGS
12 MOVE byte
13 Dir in 0,1 byte number in 2,3 Mobility in left half
14 Jump flag in bit 0 ACTIVE piece debit in left 7 bits
15 SCORE, ACTIVE's assessment of the value to him of this position
When blocks of data are to be operated on, they are moved from RAM into
the Scratchpad registers 16 thru 31. The piece debit is given special
treatment, however, since two debits must be carried forward, that for the
active side and that for the passive side. Since the sides will be
reversed when the SC is put back into RAM, the piece debit in SC is gotten
from the previous block, not the current one from which the rest of the
data is gotten. The piece debit in SC thus refers to the current passive
side while thAt in RAM refers to the active side. The debit account in SC
is increased by 1 for each promotion made by the active side and increased
by 2 for each piece captured and 3 for each king captured. At the start
of each play, the piece debit records for the board record from which the
player moves and the resulting board from which the machine plays will be
normallized by subtracting the smaller value fron both records.
The FIND routine is then entered and at that time all possible moves are
determined, the count of the number of moves is accumulated in SC 2. and
stored back into the current RAM record, leaving the mobility for the
previous board in SC which was moved to RAM from SC earlier and then on
SC where it will be useful should it turn out to be time to stop and
evaluate. However if the decision is to go further then the value from 2
is also written in byte 13 of the current SC block.
Scratchpad registers 33 to 36 are used for
EMPTY as created by code EMPTY with 32 and 37 left blank as guards
After processing the data in SC is moved back to RAM in the next block with
the ACTIVE and PASSIVE pieces reversed in position.
Scratchpad registers 0 thru 8 are normally used as follows:
Register Usage
0 general purpose
1
2 King move flag during SELECT and MOBILITY during FIND
3 Move byte during generation
4 Byte pointer (bits 2 and 3 from FLAG byte, shifted right by 2)
5 Move direction (bits 0, 1 and 4 from FLAG byte)
6 MOVE bit extracted from MOVE
7 FLAG byte for analysis
8 Color of ACTIVE (0 if Black, H'FF' if White)
Data from RAM is transfered into scratchpad registers 16 thru 31 so that
ACTIVE and PASSIVE have a LISU addres of 2,whoile KINGS and special data
have a LISU address of 3. The empty squares on the board are computed
fresh each time a board is under study and are stored with a LISU of 4.
* START
*Set up initial boards both in SC and in blocks 0 ans 1
START LISU 2
LISL 0
LI H'FF'
LR I,A First byte of ACTIVE
LI H'F0'
LR I,A Second byte of active
CLR
LR I,A Part of board with no active pieces
LR I,A Part of board with no active pieces
LR I,A Part of board with no passive pieces
LR I,A Part of board with no passive pieces
LI H'F'
LR I,A byte of PASSIVE
LI H'FF'
LR I,A Last byte with Passive pieces
LISU 3
LISL 0
CLR
LR I,A 4 king bytes next (all empty)
LR I,A
LR I,A
LR I,A
LI H'F0' The 4 leftmost bits for pieces that can move RF
LR I,A The MOVE byte
LI H'74' Mobility of 7, byte 1 and the RF direction
LR I,A
CLR Set piece debit and Jump flag to 0
LR I,A
LI H'80' Set score at -128
LR I,A
***MUST INSERT STARTING LOCATION FOR TREE DATA
LI
LR 10,A
CLR Note: H always points to the start of a block
LR 7,A This is used in keeping track of promotions
LR 11,A
LR DC,H
PI SCRC Ready for opponents move if he elects BLACK
PI SCRC Ready for Machine to play BLACK
*Now as for side election or opponents first move
**** H must be set properly as must the COLOR in SC 8
**** H is always changed by multiples of H'10'
**** K can probable be left set for Subroutine CAQ, which is probaply used
more than any one other subroutine and then this routine can be entered by
a PK rather than a PI. This will save both space and time.
Technique to choose machines first move.
If the machine is to play black then 7
possible first moves will be available in condensed form and a random
choice is made. Perhaps for the best player, the choice could be
limited to 2 or 3 of the best ones with the prefered ones repeated.
If opponent plays black then there will be stored several, probably
4, replies.
Moves are stored in a highly compressed form. Since there are seldom more
than 16 possible moves, and certainly many fewer in the opening, 4 bits
are sufficient to specify a move from any given starting location, so
moves can be packed two to the byte. By having the location of the stored
bytes computable from the number specifying the first move one can, in 7
bytes store 2 replies for each possible first move, or 4 replies in 14
words If space permits one could also store perhaps 2 counter replies each
to these replies, this taking 28 additional words. This, in effect will
cause the machine to play a different game almost every time, An astute
player can, however, note the machine play, and thus acquire a repertoire
of acceptable opening play.
To make the machine do even better with this limited storage, one might give
more weight to a prefered move by storing it twice with 2 others stored once.
* RASC SCRC EMPTY CAQ MPYR
*Subroutine to move data from RAM into SC 16 thru 31 with the data for
SC 16 thru 27 coming from the current block, 28 and 29 being set to 0 and
30 and 31 from the previous block with the Jump flag in 30 deleted.
RASC LR SC,H
LISU 2
LISL 0
LIS 8
LR 0,A
PI RASL
LISU 3
LISL 0
LIS 4
LR 0,A
PI RASL
CLR
LR I,A Zero MOVE byte
LR I,A Zero Mobility, byte # and direction info.
LR DC,H
LIS H'FE' Back up by 2
ADC
LM
NI H'FE' Save piece count portion only
LR S,A
LR A,7 Was a promotion effected last move?
NS 7
BZ RAS2
LIS 2 Add 1 (remember displacement)
AS S
LR I,A
CLR
LR 7,A Reset
LM Get score
LR I,A
POP
RASL LM
LR I,A
DS 0
BNZ RASL
POP
*Subroutine to move 16 bytes from SC 16 thru 31 to RAM direct.
SCRD LISU 2
LISL 0
LIS 8
LR 0,A
PI SCRL
LISU 3
LISL 0
LIS 8
LR 0,A
PI SCRL
POP
*Subroutine to move 16 bytes from SC 16 thru 31 to RAM, reversing ACTI and PASS
SCRC LISU 2
LISL 4
LIS 4
LR 0,A
PI SCRL
LISL 0
LIS 4
LR 0,A
PI SCRL
LISU 3
LISL 0
LIS 8
LR 0,A
PI SCRL
POP
SCRL LR A,I
ST
DS 0
BNZ SCRL
POP
*To compute 4 bytes which show the empty squares on the board.
*These are stored in SC 33 thru 36 with SC 32 and SC 37 set to zero as guards.
*Note especially that the EMPTY locations are displaced relative to ACTIVE.
EMPTY LISU 4
LISL 0
CLR
LR S,A Make sure guard byte is empty
LISU 2 Start with ACTIVE
LIS 4
LR 0,A
BR EMP3
EMP2 LR A,SI
AI H'2F' Actually subtracting 17
LR SI,A
EMP3 LR A,S
LR 1,A
LR A,IS
AI 4
LR SI,A
LR A,S
AS 1
LR 1,A
LR A,SI
AI H'D' Add 13 to get to the correct EMPTY location
LR IS,A
LR A,1
COM Reverse 1's and 0's
LR I,A
DS 0
BNZ EMP2
CLR
LR S,A Upper guard byte
POP
*Subroutine to count bits in 0 and return count in A
Uses registers 0 and 1
CAQ CLR
LR 1,A
LR A,0
BR CAQ3
CAQ2 DS 1
AI H'FF'
NS 0
LR 0,A
CAQ3 BNZ CAQ2
LR A,1
COM
AI 1 Make it into a true positive number
POP
*Subroutine to multiply 2 positive binary numbers (the smaller in SC 1 and
the larger in SC 2) by Russian multiplication where the product is not
allowed to exceed 31. This is used to compute score and a large number is
meaningless. SC 0 is used to accumulate the product. This code may be
used at only one place and can probably be written in line at that place
with some saving of space.
MPYR CLR
LR 0,A To accumulate the product
LR A,1
NS 1 To set status
BR MPY4
MPY1 NI 1 Is the rightmost bit a 1?
BZ MPY2 No
LR A,2
AS 0
LR 0,A
CI H'1E' Is the product too big?
BP MPY2 No
LI H'1E' Set it at 30
LR 0,A
BR MPY5 and stop
MPY2 LR A,2
SL 1
LR 2,A
MPY3 LR A,1
SR 1
LR 1,A
MPY4 BNZ MPY1 Product is not complete
MPY5 POP
* FKT GMEN RFJN LFJN STMV
*Subroutine to limit pieces to KINGS depending on direction and color
FKT CLR
AS 8
BR FK1
BKT LR 8 Test sides for backward move
COM
FK1 BZ FK2 NORMAL pieces can move
LISU 3 KINGS only can move
LR A,S
NS 3
LR 3,A
BZ FK3 No RF OR LF moves from this byte
FK2 LR A,3
NS 3 To set status
FK3 POP
FJET LR A,IS
AI 2 To next forward EMPTY byte (remember displacement)
LR IS,A
BJET LISU 4
LR A,S
POP
*Subroutine to get byte of ACTIVE pieces
GMEN LR A,4
LR IS,A
LISU 2
LR A,S
LR 3,A
POP
*Subroutine used both by RFJ and RJN
RFJN LR A,S
SL 4
LR 0,A
LR A,IS
AI 1
LR IS,A
LR A,S
SR 4
SR 1
AS 0
NS 3
LR 3,A The RFJ or RJ byte
POP
*Subroutine used both by LFJ and LFN
LFJN LR A,S
SL 4
SL 1
LR 0,A
LR A,IS
AI 1
LR IS,A
LR A,S
SR 4
AS 0
NS 3
LR 3,A The LFJ or LFN byte
POP
*Subroutine used both by LBJ and LBN
LBJN LR A,S
SL 4
LR 0,A
LR A,IS
AI H'FF' Back up 1
LR IS,A
LR A,S
SR 4
SR 1
AS 0
NS 3
LR 3,A
POP
*Subroutine used both by RBJ and RBN
RBJN LR A,S
SL 4
SL 1
LR 0,A
LR A,IS
AI H'FF'
LR IS,A
LR A,S
SR 4
AS 0
NS 3
LR 3,A
POP
*Subroutine to add to MOBILITY, and to store MOVE and FLAG bytes if necessary
STMV LISU 3
LISL 4 To MOVE byte
LR A,3 GET newly computed MOVE byte
LR 0,A
PI CAQ Count its bits
AS 2 Add earlier counts
LR 2,A and store
LR A,S Has one been stored?
NS S To set status byte
BNZ STM2
LIS 4
ADC
LR A,3
LR I,A Store MOVE and index to FLAG
ST Also put it in RAM record
LR A,4 Get the byte pointer
SL 1
SL 1
LR S,A Save without indexing
LR A,7
NI 3 Save the direction bits
AS S
LR I,A Now we can index
ST Also put this into RAM
LR A,7
SR 4 Extract the Jump flag
NI 1 Delete any extraneous data
AM Add it to RAM (piece count in 1 thru 7)
STM2 POP
* NEXT FIND RFJ LFJ RBJ LBJ JUMT AFT MAKE RARA
NEXT LR A,S Get FLAG byte
NI 7
AI 1
LR S,A Updated FLAG put back temporarily
NI 7
BZ AFT
LR 7,A FLAG less J bit
SR 1
SR 1
LR 4,A
LR A,7
NI 3
LR 5,A
LR A,S
XS 7
BNZ NEX2
LR A,7
AI H'10'
NEX2 DCI RFJ
ADC
LM
DCI JTAB
ADC
LR Q,DC
LR PO,Q
JTAB DC 0
DC (LFJ-RFJ)
DC (RBJ-RFJ)
DC (RFN-RFJ)
DC (LFN-RFJ)
DC (RBN-RFJ)
DC (LBN-RFJ)
FIND LISU 2
LISL 0 Start with byte 0
CLR
LR 2,A Used to accumulate mobility count by STMV
*Look for jump moves first
LIS 0
LR 4,A Used to distinguish byte
RFJ PI GMEN
PI FKT Are there forward moving pieces?
PI FJET Are jump moves in this direction posible?
SR 1
NI H'77' Save 6 particular bits only
NS 3
LR 3,A
LR A,IS
AI 2 (remember displacement)
LR IS,A
LISU 3 This gets us to the right KING byte
PI RFJN This returns the RFJ byte in 3 and sets STATUS
BZ LFJ
LI H'10' The RFJ direction and J indicator
LR 7,A
PI STMV Store MOVE ans FLAG if MOVE found and set STATUS
BZ LFJ Move already stored so must be going ahead
LR A,6 This is H'FF' if going ahead
XI H'FF'
BNZ JUMF Stop after finding a valid MOVE byte
LFJ PI GMEN
PI FKT
PI FJET Are jump moves in this direction posible?
SL 1
NI H'EE' Save 6 particular bits only
NS 3
LR 3,A
LR A,IS
AI 2 (remember displacement)
LR IS,A
LISU 3 This gets us to the right KING byte
PI LFJN This returns the LFJ byte in 3
BZ RBJ
LI H'11' The LFJ direction and J indicator
LR 7,A
PI STMV
LR A,6 This is H'FF' if going ahead
XI H'FF'
BNZ JUMF Stop after finding a valid MOVE byte
RBJ PI GMEN
PI BKT
PI BJET
SR 1
NI H'77' Save 6 particular bits only
NS 3
LR 3,A
LR A,IS
AI 2 (remember displacement)
LR IS,A
LISU 3 This gets us to the right KING byte
PI RBJN This returns the RBJ byte in 3
BZ LBJ
LI H'12' The RBJ direction and J indicator
LR 7,A
PI STMV
LR A,6 This is H'FF' if going ahead
XI H'FF'
BNZ JUMF Stop after finding a valid MOVE byte
LBJ PI GMEN
PI BKT
PI BJET
SL 1
NI H'EE' Save 6 particular bits only
NS 3
LR 3,A
LR A,IS
AI 2 (remember displacement)
LR IS,A
LISU 3 This gets us to the right KING byte
PI LBJN This returns the RBJ byte in 3
BZ JUMT
LI H'13' The RBJ direction and J indicator
LR 7,A
PI STMV
LR A,6 This is H'FF' if going ahead
XI H'FF'
BZ JUMT Stop after finding a valid MOVE byte
JUMF JMP SELE Go to SELECT on finding a move
JUMT LR A,4
AI 1
NI 3
LR 4,A
BNZ RFJ Go round again for next byte
LISU 3
LISL 4
LR A,S
NS S
BZ AFT
JMP SELE Jump move found on initial FIND
*No moves found so time to back up
AFT LR DC,H
LI H'F' Get to SCORE
ADC
LM
LR 0,A The current board score
LR A,11 Where are we?
CI H'10'
BZ MAKE Time to make move
CI H'20'
BP AFT1 Can't α-β prune if this near the start
LI H'DE'
ADC
LR A,0
CM
BP AFT3 Back 2 boards (α-β pruning)
AFT1 LR DC,H
LR A,0
COM
AI 1 Change sign of score
LR 0,A
LI H'FF'
ADC
LR A,0
CM
BP AFT2
LI H'FF'
ADC
LR A,0
ST
LI H'20' Set up to move block 2 back to block 0
LR 11,A
LR DC,H
LI H'10'
LR 0,A
PI RARA To move board from block 2 to block 0
LI H'10'
LR 11,A
LR DC,H
AFT2 JMP SELE
MAKE
*Subroutine to move a block of data back 2 levels
Used in AFT but will also be used in handling non-forked double jumps
RARA LM
LR 1,A
LI H'DF'
AS 11
LR DC,H
LR A,1
ST
LI H'1F'
AS 11
LR DC,H
DS 0
BNZ RARA
POP
* RFN LFN RBN LBN NORT
RFN PI GMEN
PI FKT
BZ RBN
LR A,I Just to index
LR A,I Just to index
LISU 4
PI RFJN
BZ LFN
CLR
LR 7,A
PI STMV
LR A,6
XI H'FF'
BNZ NORF
LFN PI GMEN
PI FKT
BZ RBN
LR A,I Just to index
LR A,I Just to index
LISU 4
PI LFJN
BZ RBN
LIS 1
LR 7,A
PI STMV
LR A,6
XI H'FF'
BNZ NORF
RBN PI GMEN
PI BKT
BZ NORT
LISU 4
PI RBJN
BZ NORT
LIS 2
LR 7,A
PI STMV
LR A,6
XI H'FF'
BNZ NORF
LBN PI GMEN
PI BKT
BZ NORT
LISU 4
PI LBJN
BZ NORT
LIS 3
LR 7,A
PI STMV
LR A,6
XI H'FF'
BZ NORT
NORF JMP SELE
NORT LR A,4
AI 1
NI 3
LR 4,A
BNZ RFN Go round again for next byte
LR A,2 Get mobility count
NS 2
BZ NRT1 Woops, no moves found
AI H'FF' Subtract 1 to conserve spase
CI 7
BP NRTX
LI 7 Limit it to 3 bits
NRTX SL 4
SL 1 Shift left by 5
LISU 3 Going ahead so we may have found one earlier
LISL 5
AS A,S
JMP FORE
NRT1 JMP AFT All moves at this level exhausted
**** SAVE MOBILITY HERE
LR A,**** But is it time to stop
***WE MUST DECIDE WHERE STOPPING LEVEL IS KEPT
AS 11
*****We will assume it is saved in COM form
BP EVAL **** We may have to do some things first
JMP SELE
* SELECT SELE
*SELECT branches to NEXT if MOVE is empty, or it extracts the rightmost
bit from the MOVE byte in RAM, storing the extracted bit in SC 6, puts the
FLAG byte in SC 7, the byte number in 4, and the J and direction bits in 5.
and proceeds to make the selected move.
SELECT LR DC,H Load DC with starting location for current ply
PI RASC Get board data into Scratchpad
SEL2 LR DC,H
LIS A,4 To get MOVE byte
ADC
LM
LR 0,A Save it temporarily
NS 0 To set status byte
BNZ SEL3
JMP NEXT To get next MOVE byte
SEL3
LI H'FE'
ADC Get back to move byte
LR A,0
AI H'FF' Really subtracting 1
NS 0 Remove right-most on-bit
ST Put remaining bits back (and index to FLAG byte)
XS 0 This gets the extracted bit
LR 6,A Save it in 6
LM
LR 5,A
SR 1
SR 1
NI 3 Separate the byte indicator part
LR 4,A Save it in 4
LM Get the Jump flag
NI 1
SL 4
AS 5
LR 5,A Save them in 5
*Now process ACTIVE and KINGS for source deletion
DELE PI GMEN
XS 6 Delete moving piece
LR S,A from byte
LISU 3 To get to corresponding KING byte
LR A,S
NS 6 Was the piece a king?
BZ DEL2
XS S If it was delete king bit
LR S,A
LI 7 Non-zero in 2 for king
DEL2 LR 2,A Save as a flag for kind of piece moving
*Now locate captured piece if jump or find destination in normal move
LR 6 Recall MOVE bit
SR 4
BZ INRH Bit was in right half of byte
INLH LR 3,A Save partially shifted MOVE bit
LR A,5 Get direction
NI 1 To test right-most bit
BZ INL2 RF or LB move where 4 shift is correct
LR A,3
SR 1 LF and LB require an additional shift
LR 3,A
INL2 LR A,5 Now test for fore or aft
NI 2
BZ BOTH Bit was off so forward move and no byte shift needed
LR A,D Only to decrement ISAR
INL3 BR BOTH
INRH LR 6 Get MOVE bit again
SL 4 Left shift if in right half
LR 3,A Save partially shifted MOVE bit
LR A,5 Get direction
NI 1
BNZ INR2 LF or RB wwhere 4 shift is correct
LR A,3
SL 1 RF and RB require an additional shift
LR 3,A
INR2 LR A,5 Now test fore and aft
NI 2
BNZ BOTH
LR A,I Only to increment ISAR
*Now we are ready to decide if jump or not
BOTH CLR
LR 0,A Used temporarily to accumulate piece debit
LR A,5 Now is this a jump or a normal move?
SR 4
BZ NORM Normal move case
LR A,S Get King Byte corresponding to captured piece
NS 3 Was piece a king?
BZ BOT2 No
XS 3 Delete it
LR S,A And replace byte
LR A,0
INC Count 1 extra for king
LR 0,A
BOT2 LIS 2
AS 0 Count 2 for piece capture
LR 0,A
LISU 2 Get back to right buffer for ACTIVE and PASSIVE
LR A,IS
AI 4 Increment to PASSIVE byte
LR IS,A
LR A,S Get appropiate PASSIVE byte
XS 3 Delete capture
LR S,A And return byte
LISU 2 Back to moved-from location
LISL 0
LR A,IS
AS 4
LR IS,A
LR A,5 Get direction
NI 1 Test for right or left
BZ BOT3
LR A,6
SR 1
BZ BOT4
BOT3 LR A,6
SL 1
BOT4 LR 3,A Save displaced bit in 3
LR A,5
NI 2 Test for fore or aft
BZ BOT5 Fore move
LR A,D Decrement ISAR
LR A,2 Was the piece a king?
NS 2
BNZ BOT6 Yes, so not necessary to test for a promotion
LR A,IS
CI H'14' Is this WHITE's king row
BNZ BOT6 No
BR BOT7
BOT5 LR A,I Increment ISAR
LR A,2
NS 2
BNZ BOT6
LR A,IS
CI H'17' Is this BLACK's king row
BNZ BOT6 No
BOT7 LIS 7
LR 2,A It is so promote piece
LR A,0
INC Add 1 to debit account
LR 0,A
BOT6 LR A,S Now get right byte
AS 3 Insert piece
LR S,A
LR A,2 Get king indicator
NS 2
BZ BOT9 Not a king
BOT8 LR A,IS
AI 4 Go to correct king byte
LR A,S
AS 3
LR S,A
BOT9 LISU 3
LISL 2
LR A,0
SL 1 Remember piece debit is displaced 1 to left
AS S
LR S,A
JMP FORE
* NORM FORE
*Now make normal move
NORM LISU 2 Get back to Active pieces
LR A,S
AS 3
LR S,A Put in moved piece
LR A,2 Was it a king
NI S
BNZ NOR6 Yes so don't promote
LR A,5
NI 2 Test for direction
BZ NOR4 Black is active
LR A,IS
CI H'14'
BNZ NOR6
BR NOR5
NOR4 LR A,IS
CI H'17'
BNZ NOR6
NOR5 LR A.0
INC
LR A,0
LIS 7
LR 2,A
NOR6 LISU 3 Now get to king byte
LR A,2 This was set to non-zero if King moving
NI 7
BZ NOR7 Not a king
LR A,S Get corresponding king byte for destination
AS 3 Insert moved king
LR S,A And replace byte
NOR7 JMP BOT9
FORE
LR DC,H
LI H'10'
ADC To next board record
LR H,DC
PI SCRA Save newly created board record
LR A,8
COM Reverse color
LR 8,A
PI RASC Get correct board into SC
LI H'FF'
LR 6,A So all moves will be found
JMP FIND
* EVAL
EVAL LR DC,H Make sure this is correct
LIS 5 To get current board mobility
ADC
LISU 3
LISL 1 To get previous board mobility
LR A,11 To find ply
SR 4
COM Make it negative
AI 3 and reduce its magnitude
LR 5,A Save it, we'll need it later
LR A,I
SR 4
LR 3,A
LM Now the current board
SR 4
COM
AI 1 Make it a true negation
AS 3
LR 3,A Mobility debit for ACTIVE
LR A,I Now for the piece advantage term
SR 1 Remember displacement
LR 2,A
LM
SR 1
LR 0,A
LR 1,A
COM
AI 1 Make it a true negation
AS 2
LR 4,A Save for its sign
BZ EVA4 No material advantage
BP EVA2
COM
AI 1 Make it a true negation
LR 1,A
LR A,0
LR 2,A
EVA2 LR A,2
AI 2 Increase larger by 2
LR 2,A
PI MPYR Multiply 2 by 1 and limit product to 30
LR A,0
SL 1
SL 1 Shift left by 2
AS 5 Subtract ply for early exploitation of advantage
LR 0,A
LR A,4
NS 4
LR A,0
BM EVA3
COM
AI 1 Make it a true negation
LR 0,A Score with sign
EVA3 LR A,0
EVA4 LR 1,A Save it
AS 3 Add in mobility difference.
LR 3,A And save in 3 (in COM form)
AS S This is the score for 2 boards earlier
BM EVAL6 Back up 2 levels (α-β pruning)
LR DC,H Otherwise back 1 level
LR H'F0'
ADC
LR H,DC
LIS H'F'
ADC
LR A,3
CM
BP EVA5
LR H'FF'
ADC Get back to right byte
LR A,3
ST Store new value
EVA5 JMP SELE
EVA6 LIS H'E0' Back 2 levels
LR DC,H
ADC
LR H,DC
JMP SELE
* SQIN SQOU MVIN
*Subroutine to accept a square number in standard checker notation in SC 1 and
to return a byte number in SC 2 and a MOVE byte (with 1 bit on) in SC 3.
SQIN LR A,1
AI H'FF'
LR 1,A
SR 1
SR 1
SR 1
LR 2,A This is the byte number
LR A,1
NI 7
LI H'80'
BR SQI2
SQI1 LR A,3
SR 1
SQI2 LR 3,A
LR A,1
AI H'FF'
LR 1,A
BNZ SQI1
POP
*Subroutine to accept a byte number in 2 and a MOVE byte in 3 and to return
a square number in standard checker notation in 1.
SQOU LR A,2
SL 1
SL 1
SL 1 Multiiply by 8
LR 1,A
SQO1 LR A,1
AI 1
LR 1,A
SQO2 LR A,3
SL 1
LR 3,A
BP SQO1
POP
*Subroutine to analyse an input move (received as two numbers in 1 and 2)
and to verify that the move is acceptable.
The general scheme is to verify certain aspects of the proposed move and
to extract the direction indicator from it. A call to FIND will then verify
that this move is indeed possible.
****THIS CODE IS MUCH TOO LONG. THERE MUST BE A BETTER WAY.
**** We must also decide on the number of messages that we may want to
generate. This code assumes only three: 1) "You must JUMP", 2) "Try again",
or perhaps "Illegal move" and 3) "O.K.".
MVIN CLR
LR 11,A
LR DC,H
LI H'E'
ADC
LM
NI 1 Extract J
LR 3,A Save as required Jump flag
LR A,1
COM
AI 1
AS 2
LR 4,A Save for front or back move signal
BP MVI2
COM
AI 1
MVI2 LR 5,A Save magnitude of difference
CI 6
BM MVJ1 Seems to be a jump move
LR A,1
NI 1
BZ MVN2 Normal move called for
JMP ERR1 An error, Jump is required
MVN2 CI 3
BZ MVN3 Must be RF or LB
CI 5
BZ MVN4 Must be LF or RB
CI 4
BZ MVN5 Can not decide yet
JMP ERR2 An error, normal move required
MVN5 LR A,1
AI H'FF' Subtract 1
NI 4 Which half of byte
BNZ MVN4 Must be LF or RB
MVN3 LR A,4 A RF or LB
NS 4
BM MVN6
CLR RF
BR MVI3
MVN6 LI 3 LB
BR MVI3
MVN4 LR A,4
NS 4
BM MVN7
LI 1 LF
BR MVI3
MVN7 LI 2 RB
BR MVI3
MVJ1 LR A,1
NI 1
BNZ MVJ2
JMP ERR2 An error, normal move required
MVJ2 LR A,5
CI 7
BZ MVJ3 It's either RFJ or LBJ
CI 9
BZ MVJ5 It's either LFJ or RBJ
JMP ERR1 An error, jump is required
MVJ3 LR A,4
NS 4
BM MVJ4
LI H'10' RFJ
BR MVI3
MVJ4 LI H'13' LBJ
BR MVI3
MVJ5 LR A,4
NS 4
BM MVJ6
LI H'11' LFJ
BR MVI3
MVJ6 LI H'12' RBJ
BR MVI3
MVI3 LR 0,A Save temporarily
**** Now we must fix matters so that FIND may be called to see if this is
a legel move
**** Then we do the following
PI SQIN Get the byte number into 2 and the move byte into 3
LR DC,H
PI RASC
LR DC,H
LR A,3
LR 6,A
LR A,2
SL 1
SL 1
AS 0 THIS HAS THE JUMP BIT IN H'10'
**** This has the JUMP bit in the original FLAG byte
**** We are about ready to enter SELECT at about DELE but some fixing is necessary